package com.zmn.plat.business.impl.service.tariff;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.zmn.plat.business.interfaces.channel.ChannelServiceCategoryBService;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.plat.business.interfaces.service.tariff.ServiceTariffBService;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.manager.dictionary.ProductDict;
import com.zmn.plat.model.entity.channel.ChannelFaultPriceVO;
import com.zmn.plat.model.entity.product.*;
import com.zmn.plat.model.entity.product.tariff.ProductTariff;
import com.zmn.plat.model.entity.product.tariff.ProductTariffQuery;
import com.zmn.plat.model.entity.product.tariff.group.ProductTariffGroup;
import com.zmn.plat.model.entity.product.tariff.item.ProductTariffGroupItem;
import com.zmn.plat.model.entity.product.tariff.item.ProductTariffGroupItemQuery;
import com.zmn.plat.model.entity.product.tariff.item.city.price.ProductTariffItemCityPrice;
import com.zmn.plat.model.entity.service.group.ServiceGroup;
import com.zmn.plat.model.entity.service.group.ServiceGroupQuery;
import com.zmn.plat.model.entity.service.item.ServiceItem;
import com.zmn.plat.model.entity.service.item.config.ServiceItemTimeConfig;
import com.zmn.plat.model.entity.service.tariff.ServiceTariff;
import com.zmn.plat.model.entity.service.tariff.ServiceTariffQuery;
import com.zmn.plat.model.entity.warranty.info.WarrantyInfo;
import com.zmn.plat.model.entity.warranty.info.WarrantyInfoQuery;
import com.zmn.plat.model.vo.product.tariff.ProductTariffVO;
import com.zmn.plat.model.vo.service.group.ServiceGroupVO;
import com.zmn.plat.model.vo.service.item.ServiceItemVO;
import com.zmn.plat.model.vo.service.tariff.ServiceTariffRelationVO;
import com.zmn.plat.model.vo.service.tariff.ServiceTariffVO;
import com.zmn.plat.services.interfaces.channel.tariff.ChannelTariffService;
import com.zmn.plat.services.interfaces.product.ServProductRelationService;
import com.zmn.plat.services.interfaces.product.ServProductService;
import com.zmn.plat.services.interfaces.product.ServTariffProductRelationService;
import com.zmn.plat.services.interfaces.product.tariff.ProductTariffService;
import com.zmn.plat.services.interfaces.product.tariff.group.ProductTariffGroupService;
import com.zmn.plat.services.interfaces.product.tariff.item.ProductTariffGroupItemService;
import com.zmn.plat.services.interfaces.product.tariff.item.city.price.ProductTariffItemCityPriceService;
import com.zmn.plat.services.interfaces.service.group.ServiceGroupService;
import com.zmn.plat.services.interfaces.service.item.ServiceItemService;
import com.zmn.plat.services.interfaces.service.item.config.ServiceItemTimeConfigService;
import com.zmn.plat.services.interfaces.service.tariff.ServiceTariffService;
import com.zmn.plat.services.interfaces.warranty.info.WarrantyInfoService;

/**
 * @author tanbiao
 * @description
 * @since 2019/11/22 15:45
 * @modifier
 **/
@Service
public class ServiceTariffBServiceImpl implements ServiceTariffBService {
    @Resource
    private ServiceTariffService faultTariffService;
    @Resource
    private ProductTariffService productFaultTariffService;
    @Resource
    private ProductTariffGroupItemService productFaultItemService;
    @Resource
    private ServiceItemService faultItemService;
    @Resource
    private ServiceGroupService faultGroupService;
    @Resource
    private ProductTariffItemCityPriceService faultItemCityPriceService;
    @Resource
    private ProductTariffGroupService productFaultGroupService;
    @Resource
    ChannelTariffService channelTariffService;
    @Resource
    ServTariffProductRelationService tariffProductRelationService;
    @Resource
    ServProductService servProductService;
    @Resource
    ServProductRelationService servProductRelationService;
    @Resource
    WarrantyInfoService warrantyInfoService;
    @Resource
    private ServiceItemTimeConfigService faultItemTimeConfigService;
    @Resource
    ChannelServiceCategoryBService channelServiceCategoryBService;

    @Override
    public ServiceTariff findByKey(Integer tariffId) {
        ServiceTariff faultTariff;
        if (tariffId == null || tariffId == 0) {
            faultTariff = new ServiceTariff();
        } else {
            faultTariff = Optional.ofNullable(faultTariffService.findByKey(tariffId)).orElse(new ServiceTariff());
        }
        // 排序默认最大排序加1
        if (faultTariff.getSort() == null) {
            Integer sort = faultTariffService.findMaxSort();
            sort = sort == null ? 1 : sort + 1;
            faultTariff.setSort(sort);
        }
        return faultTariff;
    }

    /**
     * 功能描述 保内/保外下的某价格表类型下的价格表名称不能相同
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer insertAll(ServiceTariff faultTariff, String creater) {
        checkParams(faultTariff);
        // 1.同类型价格表名称不可重复
        ServiceTariffQuery query = new ServiceTariffQuery();
        query.setTariffName(faultTariff.getTariffName());
        query.setBizType(faultTariff.getBizType());
        query.setTariffType(faultTariff.getTariffType());
        List<ServiceTariff> list = faultTariffService.listByQuery(query);
        if (!CollectionUtils.isEmpty(list)) {
            throw new PlatException("价格表名称不可重复");
        }
        // 2.同类型价格表最多一个默认价格表
        // if(faultTariff.getGeneral().equals(GlobalConsts.YES)){
        // query = new ServiceTariffQuery();
        // query.setKeepType(faultTariff.getKeepType());
        // query.setGeneral(GlobalConsts.YES);
        // list = faultTariffService.listByQuery(query);
        // if(!CollectionUtils.isEmpty(list)){
        // throw new PlatException("价格表最多一个默认价格表");
        // }
        // //4、默认价格表不可被停用
        // if(faultTariff.getStatus().equals(GlobalConsts.NO)){
        // throw new PlatException("默认价格表不可被停用");
        // }
        // }
        faultTariff.setCreater(creater);
        faultTariff.setCreateTime(new Date());
        faultTariff.setUpdater(creater);
        faultTariff.setUpdateTime(new Date());
        return faultTariffService.insert(faultTariff);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateAll(ServiceTariff faultTariff, String updater) {
        checkParams(faultTariff);
        // 1.同类型价格表名称不可重复
        ServiceTariffQuery query = new ServiceTariffQuery();
        query.setTariffName(faultTariff.getTariffName());
        query.setBizType(faultTariff.getBizType());
        query.setTariffType(faultTariff.getTariffType());
        List<ServiceTariff> list = faultTariffService.listByQuery(query);
        if (!CollectionUtils.isEmpty(list)) {
            if (list.size() > 1 || !list.get(0).getTariffId().equals(faultTariff.getTariffId())) {
                throw new PlatException("价格表名称不可重复");
            }
        }
        // 2.同类型价格表最多一个默认价格表
        // if(faultTariff.getGeneral().equals(GlobalConsts.YES)){
        // query = new ServiceTariffQuery();
        // query.setKeepType(faultTariff.getKeepType());
        // query.setGeneral(GlobalConsts.YES);
        // list = faultTariffService.listByQuery(query);
        // if(!CollectionUtils.isEmpty(list)){
        // if(list.size()>1||!list.get(0).getTariffId().equals(faultTariff.getTariffId())){
        // throw new PlatException("价格表最多一个默认价格表");
        // }
        // }
        // //4、默认价格表不可被停用
        // if(faultTariff.getStatus().equals(GlobalConsts.NO)){
        // throw new PlatException("默认价格表不可被停用");
        // }
        // }
        // 3.停用价格表，则其关联的服务分类+后台一级产品分类的价格表，以及：产品关联的价格表，也都将禁用
        if (faultTariff.getStatus().equals(GlobalConsts.NO)) {
            ProductTariffQuery productFaultTariffQuery = new ProductTariffQuery();
            productFaultTariffQuery.setGeneral(GlobalConsts.YES);
            productFaultTariffQuery.setTariffId(faultTariff.getTariffId());
            List<ProductTariffVO> generalList = productFaultTariffService.listByQuery(productFaultTariffQuery);
            if (generalList != null && generalList.size() > 0) {
                throw new PlatException("默认价格表不可被停用");
            }
            productFaultTariffService.updateStatusByTariffIds(Arrays.asList(faultTariff.getTariffId()), faultTariff.getStatus(), updater);
        }
        faultTariff.setUpdateTime(new Date());
        faultTariff.setUpdater(updater);
        return faultTariffService.updateByKey(faultTariff);
    }

    /**
     * 更新状态,需要进行的检查 1.停用价格表，则其关联的服务分类+后台一级产品分类的价格表，以及：产品关联的价格表，也都将禁用 2、默认价格表不可被停用
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateStatusBatchByKey(List<Integer> ids, Integer status, String mcStaffName) {
        List<ServiceTariff> list = faultTariffService.findByKeys(ids);
        // 启用不做任何限制，禁用需要排除默认价格表，同时级联禁用其他价格表
        if (status == null) {
            throw new PlatException("状态参数缺失");
        }

        if (status.equals(GlobalConsts.NO)) {
            ProductTariffQuery query = new ProductTariffQuery();
            query.setGeneral(GlobalConsts.YES);
            query.setTariffIds(ids);
            List<ProductTariffVO> generalList = productFaultTariffService.listByQuery(query);
            if (generalList != null && generalList.size() > 0) {
                StringBuilder stringBuilder = new StringBuilder();
                generalList.forEach(e -> stringBuilder.append(e.getTariffId()).append(","));
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                throw new PlatException("默认价格表不可被停用");
            }
            productFaultTariffService.updateStatusByTariffIds(ids, status, mcStaffName);
        }
        return faultTariffService.updateStatusBatchByKey(ids, status, mcStaffName);
    }

    @Override
    public List<ServiceGroup> listGroupByTariffIdAndServCategIdAndCategOneId(Integer tariffId, Integer servCategId, Integer categOneId) {
        ServiceGroupQuery faultGroupQuery = new ServiceGroupQuery();
        faultGroupQuery.setTariffId(tariffId);
        // 如果是全部的情况，服务分类和产品分类特殊处理
        faultGroupQuery.setServCategId((servCategId == null || servCategId.equals(GlobalConsts.NO)) ? null : servCategId);
        faultGroupQuery.setCategOneId((categOneId == null || categOneId.equals(GlobalConsts.NO)) ? null : categOneId);
        List<ServiceGroup> faultGroups = faultGroupService.listByTariffIdAndServCategIdAndCategOneId(faultGroupQuery);
        return faultGroups;
    }

    @Override
    public ServiceTariff getTariffByChannelIdAndProductIdAndShowTypeAndType(Integer channelId, Integer productId, Integer traiffType, Integer showType, Integer type) {

        // 如果是前台产品，查询对应上架的后台产品，如果上架后台产品数大于1,则没有价格表信息
        if (Objects.equals(showType, ProductConsts.EC_PRODUCT_TYPE)) {
            return this.getShowTariffByChannelIdAndProductIdAndType(channelId, productId, traiffType, type);
        }

        // 如果是计价器产品，查询对应上架的后台产品，如果上架后台产品数大于1,则没有价格表信息
        if (Objects.equals(showType, ProductConsts.ET_PRODUCT_TYPE)) {
            return this.getTariffTariffByChannelIdAndProductIdAndType(channelId, productId, traiffType, type);
        }

        // 如果是后台产品，直接查询价格表信息
        if (Objects.equals(showType, ProductConsts.ERP_PRODUCT_TYPE)) {
            return this.getBackTariffByChannelIdAndProductIdAndType(channelId, productId, traiffType, type);
        }

        return null;
    }

    /**
     * 描述: 获取前台产品价格表
     *
     * @param channelId
     *            渠道ID
     * @param type
     *            保内保外
     * @param traiffType
     *            价格表类型
     * @param productId
     *            产品ID
     * @return
     * @auther tanghongjun
     * @since 2020/3/27 16:45
     */
    public ServiceTariff getShowTariffByChannelIdAndProductIdAndType(Integer channelId, Integer productId, Integer traiffType, Integer type) {

        // 计价器服务项
        if (Objects.equals(traiffType, ProductDict.TRIFF_TYPE_TARIFF)) {
            // 根据前台产品ID查询支持计价器的后台产品
            List<ServProduct> servProductList = servProductService.listSupportByShowProductId(productId);
            return getBackTariffByChannelIdAndProductListAndType(channelId, servProductList, traiffType, type);
        }

        // 普通服务项
        if (Objects.equals(traiffType, ProductDict.TRIFF_TYPE_SERVICE)) {
            // 根据前台产品ID查询支持计价器的后台产品
            ServProductRelationQuery query = new ServProductRelationQuery();
            query.setShowProductId(productId);
            List<ServProductRelation> servProductRelationList = servProductRelationService.listByQuery(query);
            List<Integer> productIdList = servProductRelationList.stream().map(ServProductRelation::getProductId).collect(Collectors.toList());
            List<ServProduct> servProductList = servProductService.listByIdList(productIdList);
            return getBackTariffByChannelIdAndProductListAndType(channelId, servProductList, traiffType, type);
        }

        return null;
    }

    /**
     * 描述: 获取计价器产品价格表
     *
     * @param channelId
     *            渠道ID
     * @param type
     *            保内保外
     * @param traiffType
     *            价格表类型
     * @param productId
     *            产品ID
     * @return
     * @auther tanghongjun
     * @since 2020/3/27 16:45
     */
    public ServiceTariff getTariffTariffByChannelIdAndProductIdAndType(Integer channelId, Integer productId, Integer traiffType, Integer type) {

        // 计价器产品，判断对应上架的后台产品是否大约1
        ServTariffProductRelationQuery query = new ServTariffProductRelationQuery();
        query.setTariffProductId(productId);
        List<ServTariffProductRelation> tariffProductRelationList = tariffProductRelationService.listByQuery(query);

        // 如果计价器产品没有对应后台产品，不支持一口价
        if (CollectionUtil.isNullOrEmpty(tariffProductRelationList)) {
            return null;
        }

        List<Integer> productIdList = tariffProductRelationList.stream().map(ServTariffProductRelation::getProductId).collect(Collectors.toList());
        List<ServProduct> servProductList = servProductService.listByIdList(productIdList);

        return getBackTariffByChannelIdAndProductListAndType(channelId, servProductList, traiffType, type);
    }

    /**
     * 描述: 根据后台产品列表，查询价格表
     *
     * @param channelId
     *            渠道ID
     * @param type
     *            保内保外
     * @param traiffType
     *            价格表类型
     * @param servProductList
     *            产品集合
     * @return
     * @auther tanghongjun
     * @since 2020/3/27 16:45
     */
    public ServiceTariff getBackTariffByChannelIdAndProductListAndType(Integer channelId, List<ServProduct> servProductList, Integer traiffType, Integer type) {
        List<ServProduct> supportTariffProduct = new ArrayList<>();
        ServProduct servProduct;
        ServiceTariff faultTariff = null;
        for (int i = 0; i < servProductList.size(); i++) {
            servProduct = servProductList.get(i);
            if (Objects.equals(servProduct.getStatus(), GlobalConsts.NO)) {
                continue;
            }

            faultTariff = getBackTariffByChannelIdAndProductIdAndType(channelId, servProduct.getProductId(), traiffType, type);
            if (Objects.nonNull(faultTariff)) {
                supportTariffProduct.add(servProduct);
            }
        }

        if (supportTariffProduct.size() == 1) {
            return faultTariff;
        } else {
            return null;
        }
    }

    /**
     * 描述: 获取后台产品价格表
     *
     * @param channelId
     *            渠道ID
     * @param type
     *            保内保外
     * @param traiffType
     *            价格表类型
     * @param productId
     *            产品ID
     * @return
     * @auther tanghongjun
     * @since 2020/3/27 16:45
     */
    public ServiceTariff getBackTariffByChannelIdAndProductIdAndType(Integer channelId, Integer productId, Integer traiffType, Integer type) {
        // 判断渠道是否开通分类，如果已开通则取当前渠道，反之取上级渠道信息
        try {
            channelId = channelServiceCategoryBService.getAvailableCategoryChannelId(channelId);
        } catch (PlatException e){
            return null;
        }

        // 查询渠道配置的价格表
        ChannelFaultPriceVO channelFault = channelTariffService.findByChannelIdAndBizTypeAndTariffType(channelId, type, traiffType);
        int traiffId = 0;
        if (Objects.nonNull(channelFault)) {
            traiffId = channelFault.getTariffId();
        }
        ServProduct servProduct = servProductService.findByKey(productId);
        Boolean flag = Objects.equals(traiffType, ProductDict.TRIFF_TYPE_TARIFF) && Objects.equals(servProduct.getTariffStatus(), GlobalConsts.NO);
        if (Objects.equals(servProduct.getStatus(), GlobalConsts.NO) || flag) {
            return null;
        }

        // 检查后台产品渠道价格表是否可用
        if (NumberUtil.isPositiveInteger(traiffId)) {
            ServiceTariff faultTariffa = faultTariffService.findByKey(channelFault.getTariffId());
            if (Objects.nonNull(faultTariffa) && Objects.equals(faultTariffa.getStatus(), GlobalConsts.YES)) {
                // 判断产品在当前价格表下是否可以用
                ProductTariffGroupItemQuery itemQuery = new ProductTariffGroupItemQuery();
                itemQuery.setProductId(servProduct.getProductId());
                itemQuery.setTariffId(traiffId);
                int count = productFaultItemService.countByQuery(itemQuery);
                if (count > 0) {
                    return faultTariffa;
                }
            }
        }

        // 价差(检查)后台产品通用价格表是否可用
        // 查询产品通用价格表
        ProductTariffQuery tariffQuery = new ProductTariffQuery();
        tariffQuery.setProductId(productId);
        tariffQuery.setBizType(type);
        tariffQuery.setGeneral(GlobalConsts.YES);
        tariffQuery.setTariffType(traiffType);
        List<ProductTariffVO> tariffVOS = productFaultTariffService.listByQuery(tariffQuery);
        if (CollectionUtil.isNotNullOrEmpty(tariffVOS)) {
            ServiceTariff faultTariffb = faultTariffService.findByKey(tariffVOS.get(0).getTariffId());
            if (Objects.nonNull(faultTariffb) && Objects.equals(faultTariffb.getStatus(), GlobalConsts.YES)) {
                // 判断产品在当前价格表下是否可以用
                ProductTariffGroupItemQuery itemQuery = new ProductTariffGroupItemQuery();
                itemQuery.setProductId(servProduct.getProductId());
                itemQuery.setTariffId(faultTariffb.getTariffId());
                int count = productFaultItemService.countByQuery(itemQuery);
                if (count > 0) {
                    return faultTariffb;
                }
            }
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyTariff(ServiceTariffVO faultTariffVO, String mcStaffRealName) {
        // 服务分类为全部时，特殊处理为服务分类null，同时产品二级分类为null
        if (faultTariffVO.getServCategId().equals(GlobalConsts.NO)) {
            faultTariffVO.setServCategId(null);
            faultTariffVO.setCategOneId(null);
        }
        if (null != faultTariffVO.getCategOneId() && faultTariffVO.getCategOneId().equals(GlobalConsts.NO)) {
            faultTariffVO.setCategOneId(null);
        }

        ServiceTariffRelationVO vo = getAllRelationData(faultTariffVO, mcStaffRealName);
        // 原价格表数据为空，直接拷贝新价格表所属服务分类产品一级分类数据
        if (CollectionUtils.isEmpty(vo.getOrgFaultGroupList())) {
            addAllRelatedData(vo);
        }
        // 被复制价格表数据为空，清空原价格表所属服务分类产品一级分类数据
        else if (CollectionUtils.isEmpty(vo.getNewFaultGroupList())) {
            removeAllRelatedData(vo);
        }
        // 二者都存在数据，采取删除元价格表和被复制价格表中相同数据，再插入被复制价格表中的数据
        else {
            removeAllRelatedData(vo);
            addAllRelatedData(vo);
        }
    }

    /**
     * 功能描述 :被复制价格表数据为空，清空原价格表所属服务分类产品一级分类数据
     *
     * @param vo
     * @return void
     * @author tanbiao
     * @since 2020/3/6
     * @modifier
     */
    private void removeAllRelatedData(ServiceTariffRelationVO vo) {
        // 服务分组id
        List<Integer> faultGroupIds = vo.getOrgFaultGroupList().stream().map(e -> e.getGroupId()).collect(Collectors.toList());
        productFaultTariffService.deleteByTariffIdAndServCategIdAndCategOneId(vo.getFaultTariffVO().getOrganTariffId(), vo.getFaultTariffVO().getServCategId(), vo.getFaultTariffVO().getCategOneId());
        // 删除分组
        faultGroupService.deleteByGroupIds(faultGroupIds);
        // 删除服务项
        faultItemService.deleteByGroupIds(faultGroupIds);
        // 删除价格表
        productFaultItemService.deleteByGroupIds(faultGroupIds);
        faultItemCityPriceService.deleteByGroupIds(faultGroupIds);
        // 缺乏分组，需要根据产品id和价格表id进行关联
        productFaultGroupService.deleteByGroupIds(faultGroupIds);

        // 删除原价格表保修信息
        warrantyInfoService.deleteByTariffIdAndServCategIdAndCategOneId(vo.getFaultTariffVO().getOrganTariffId(), vo.getFaultTariffVO().getServCategId(), vo.getFaultTariffVO().getCategOneId());
    }

    private ServiceTariffRelationVO getAllRelationData(ServiceTariffVO faultTariffVO, String mcStaffRealName) {
        ServiceTariffRelationVO vo = new ServiceTariffRelationVO();
        // 1.查询只能复制通用产品的价格表，如果不存在通用产品，给出提示
        List<ServiceGroup> newFaultGroupList = listGroupByTariffIdAndServCategIdAndCategOneId(faultTariffVO.getNewTariffId(), faultTariffVO.getServCategId(), faultTariffVO.getCategOneId());
        // 2.查询原价格表数据
        List<ServiceGroup> orgFaultGroupList = listGroupByTariffIdAndServCategIdAndCategOneId(faultTariffVO.getOrganTariffId(), faultTariffVO.getServCategId(), faultTariffVO.getCategOneId());
        // 两个价格表数据都为空
        if (CollectionUtils.isEmpty(newFaultGroupList) && CollectionUtils.isEmpty(orgFaultGroupList)) {
            throw new PlatException("原价格表和被复制价格表都无数据，不执行复制");
        }
        vo.setNewFaultGroupList(newFaultGroupList);
        vo.setOrgFaultGroupList(orgFaultGroupList);
        vo.setFaultTariffVO(faultTariffVO);
        // 服务分组id
        List<Integer> faultGroupIds = newFaultGroupList.stream().map(e -> e.getGroupId()).collect(Collectors.toList());
        // 3.被复制价格表可能被复制的所有数据（分组数据前面已经获取了）
        if (CollectionUtils.isEmpty(faultGroupIds)) {
            return vo;
        }
        // 项目
        List<ServiceItem> faultItemList = faultItemService.listByGroupIds(faultGroupIds);
        // 城市价格(以下四个需要建立价格表和产品的关系之后才会出现，也就是在“设置价格表”提交之后才会有，此时才认为产品和价格表之间建立了联系)
        List<ProductTariffItemCityPrice> itemCityPriceList = faultItemCityPriceService.listByGroupIds(faultGroupIds);
        // 产品价格分组关联关系（）
        List<ProductTariffGroup> productFaultGroupList = productFaultGroupService.listByGroupIds(faultGroupIds);
        // 产品价格表
        List<ProductTariffGroupItem> productFaultItemList = productFaultItemService.listByGroupIds(faultGroupIds);
        // 产品和价格表关联关系
        List<ProductTariff> productFaultTariffList =
            productFaultTariffService.listByTariffIdAndServCategIdAndCategOneId(faultTariffVO.getNewTariffId(), faultTariffVO.getServCategId(), faultTariffVO.getCategOneId());
        // 时间配置信息
        // 产品价格表
        List<ServiceItemTimeConfig> faultItemTimeConfigs = faultItemTimeConfigService.listByGroupIds(faultGroupIds);

        vo.setItemCityPriceList(itemCityPriceList);
        vo.setProductFaultGroupList(productFaultGroupList);
        vo.setProductFaultItemList(productFaultItemList);
        vo.setProductFaultTariffList(productFaultTariffList);
        vo.setFaultItemList(faultItemList);
        vo.setFaultItemTimeConfigs(faultItemTimeConfigs);
        vo.setOpreator(mcStaffRealName);

        // 处理保修信息
        WarrantyInfoQuery warrantyInfoQuery = new WarrantyInfoQuery();
        warrantyInfoQuery.setTariffId(vo.getFaultTariffVO().getNewTariffId());
        warrantyInfoQuery.setServCategId(vo.getFaultTariffVO().getServCategId());
        warrantyInfoQuery.setCategOneId(vo.getFaultTariffVO().getCategOneId());
        List<WarrantyInfo> warrantyInfos = warrantyInfoService.listByQuery(warrantyInfoQuery);
        vo.setWarrantyInfos(warrantyInfos);

        return vo;
    }

    private void addAllRelatedData(ServiceTariffRelationVO vo) {
        // 批量插入不会返回id，因此针对分组，只能单条数据的插入，获取插入之后的id
        List<ServiceGroup> newFaultGroupList = vo.getNewFaultGroupList();
        List<ServiceItem> faultItemList = vo.getFaultItemList();
        List<ProductTariffGroup> productFaultGroupList = vo.getProductFaultGroupList();
        List<ProductTariffGroupItem> productFaultItemList = vo.getProductFaultItemList();
        List<ProductTariffItemCityPrice> itemCityPriceList = vo.getItemCityPriceList();
        List<ProductTariff> productFaultTariffList = vo.getProductFaultTariffList();
        List<WarrantyInfo> warrantyInfos = vo.getWarrantyInfos();
        List<ServiceItemTimeConfig> timeConfigs = vo.getFaultItemTimeConfigs();

        Integer tariffId = vo.getFaultTariffVO().getOrganTariffId();
        ServiceTariff organFaultTariff = faultTariffService.findByKey(tariffId);
        String operator = vo.getOpreator();
        // 批量插入服务分组
        Map<Integer, Integer> groupNewOldRelationMap = new HashMap<>();
        Map<Integer, Integer> itemNewOldRelationMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(newFaultGroupList)) {
            BeanCopier groupCopier = BeanCopier.create(ServiceGroup.class, ServiceGroupVO.class, false);
            List<ServiceGroupVO> newFaultGroupVoList = newFaultGroupList.stream().map(e -> {
                ServiceGroupVO newFaultGroupVo = new ServiceGroupVO();
                setCommonGroupMsg(e, tariffId, operator);
                groupCopier.copy(e, newFaultGroupVo, null);
                newFaultGroupVo.setOldGroupId(e.getGroupId());
                return newFaultGroupVo;
            }).collect(Collectors.toList());
            faultGroupService.insertBatch(newFaultGroupVoList);
            // 整理出新旧关系
            newFaultGroupVoList.forEach(e -> groupNewOldRelationMap.put(e.getOldGroupId(), e.getGroupId()));
        }

        // 处理完，批量执行批量插入项目
        if (!CollectionUtils.isEmpty(faultItemList)) {
            BeanCopier itemCopier = BeanCopier.create(ServiceItem.class, ServiceItemVO.class, false);
            List<ServiceItemVO> newFaultItemVoList = faultItemList.stream().map(e -> {
                setItemCommonMsg(e, groupNewOldRelationMap.get(e.getGroupId()), tariffId, operator);
                ServiceItemVO newFaultItemVo = new ServiceItemVO();
                itemCopier.copy(e, newFaultItemVo, null);
                newFaultItemVo.setOldItemId(e.getItemId());
                return newFaultItemVo;
            }).collect(Collectors.toList());
            faultItemService.insertBatch(newFaultItemVoList);
            // 整理出新旧关系
            newFaultItemVoList.forEach(e -> itemNewOldRelationMap.put(e.getOldItemId(), e.getItemId()));
        }
        if (!CollectionUtils.isEmpty(productFaultGroupList)) {
            productFaultGroupList.forEach(e -> {
                setProductFaultGroupCommonMsg(e, groupNewOldRelationMap.get(e.getGroupId()), tariffId, operator);
            });
            productFaultGroupService.insertBatch(productFaultGroupList);
        }
        if (!CollectionUtils.isEmpty(productFaultItemList)) {
            productFaultItemList.forEach(e -> {
                setProductFaultItemCommonMsg(e, groupNewOldRelationMap.get(e.getGroupId()), tariffId, operator, itemNewOldRelationMap.get(e.getItemId()));
            });
            productFaultItemService.insertBatch(productFaultItemList);
        }
        if (!CollectionUtils.isEmpty(itemCityPriceList)) {
            itemCityPriceList.forEach(e -> {
                setCityPriceCommonMsg(e, groupNewOldRelationMap.get(e.getGroupId()), tariffId, operator, itemNewOldRelationMap.get(e.getItemId()));
            });
            faultItemCityPriceService.insertBatch(itemCityPriceList);
        }
        if (!CollectionUtils.isEmpty(productFaultTariffList)) {
            // 产品价格关系不存在分组，直接赋值新的价格表id和公共信息
            productFaultTariffList.forEach(e -> setProductFaultTariffCommonMsg(e, organFaultTariff, operator));
            productFaultTariffService.insertBatch(productFaultTariffList);
        }

        /**
         * 处理保修信息
         */
        if (!CollectionUtils.isEmpty(warrantyInfos)) {
            List<WarrantyInfo> insertWarrantyInfos = new ArrayList<>();
            WarrantyInfo warrantyInfo;
            for (int i = 0; i < warrantyInfos.size(); i++) {
                warrantyInfo = warrantyInfos.get(i);
                if(NumberUtil.isPositiveInteger(itemNewOldRelationMap.get(warrantyInfo.getItemId()))){
                    setWarrantyInfoCommonMsg(warrantyInfo, tariffId, operator, itemNewOldRelationMap.get(warrantyInfo.getItemId()));
                    insertWarrantyInfos.add(warrantyInfo);
                }
            }

            if(CollectionUtil.isNotNullOrEmpty(insertWarrantyInfos)){
                warrantyInfoService.insertBatch(insertWarrantyInfos);
            }
        }
        // 处理时间配置信息
        if (!CollectionUtils.isEmpty(timeConfigs)) {
            timeConfigs.forEach(e -> {
                setTimeConfigCommonMsg(e, tariffId, operator, itemNewOldRelationMap.get(e.getItemId()), groupNewOldRelationMap.get(e.getGroupId()));
            });
            faultItemTimeConfigService.insertBatch(timeConfigs);
        }

    }

    private void setProductFaultTariffCommonMsg(ProductTariff e, ServiceTariff faultTariff, String operator) {
        e.setTariffId(faultTariff.getTariffId());
        e.setTariffName(faultTariff.getTariffName());
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setStatus(GlobalConsts.NO);
        e.setGeneral(GlobalConsts.NO);
        e.setUpdater(operator);
        e.setCreater(operator);
    }

    private void setProductFaultItemCommonMsg(ProductTariffGroupItem e, Integer groupId, Integer tariffId, String operator, Integer itemId) {
        e.setGroupId(groupId);
        e.setTariffId(tariffId);
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
        e.setItemId(itemId);
    }

    private void setWarrantyInfoCommonMsg(WarrantyInfo e, Integer tariffId, String operator, Integer itemId) {
        e.setTariffId(tariffId);
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
        e.setItemId(itemId);
    }

    private void setTimeConfigCommonMsg(ServiceItemTimeConfig e, Integer tariffId, String operator, Integer itemId, Integer groupId) {
        e.setTariffId(tariffId);
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
        e.setItemId(itemId);
        e.setGroupId(groupId);
    }

    private void setProductFaultGroupCommonMsg(ProductTariffGroup e, Integer groupId, Integer tariffId, String operator) {
        e.setGroupId(groupId);
        e.setTariffId(tariffId);
        e.setUpdateTime(new Date());
        e.setCreateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
    }

    private void setCityPriceCommonMsg(ProductTariffItemCityPrice e, Integer groupId, Integer tariffId, String operator, Integer itemId) {
        e.setGroupId(groupId);
        e.setTariffId(tariffId);
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
        e.setItemId(itemId);
    }

    private void setItemCommonMsg(ServiceItem e, Integer groupId, Integer tariffId, String operator) {
        e.setGroupId(groupId);
        e.setTariffId(tariffId);
        e.setCreateTime(new Date());
        e.setUpdateTime(new Date());
        e.setUpdater(operator);
        e.setCreater(operator);
    }

    private void setCommonGroupMsg(ServiceGroup faultGroup, Integer tariffId, String operator) {
        faultGroup.setTariffId(tariffId);
        faultGroup.setCreater(operator);
        faultGroup.setUpdater(operator);
        faultGroup.setCreateTime(new Date());
        faultGroup.setUpdateTime(new Date());
        String newAliasName = faultGroup.getGroupAlias();
        if (newAliasName.length() > 50) {
            newAliasName = newAliasName.substring(0, 49);
        }
        faultGroup.setGroupAlias(newAliasName);
        String groupName = faultGroup.getGroupName();
        if (groupName.length() > 50) {
            groupName = groupName.substring(0, 49);
        }
        faultGroup.setGroupName(groupName);
    }

    private void checkParams(ServiceTariff faultTariff) {
        if (faultTariff.getBizType() == null) {
            throw new PlatException("保内保外参数缺失");
        }
        if (faultTariff.getTariffType() == null) {
            throw new PlatException("价格表类型参数缺失");
        }
        if (faultTariff.getPriceType() == null) {
            throw new PlatException("定价方式参数缺失");
        }
        if (faultTariff.getStatus() == null) {
            throw new PlatException("状态参数缺失");
        }
    }
}
